package com.sense.cloud.coreservice.sdk.auth.modules;


import com.sense.cloud.coreservice.sdk.auth.utils.MD5Utils;
import com.sense.cloud.coreservice.sdk.auth.utils.SdkPropUtil;
import com.sense.cloud.coreservice.sdk.auth.utils.StringUtils;
import com.sense.cloud.coreservice.sdk.auth.utils.http.assist.AuthConstants;
import com.sense.cloud.coreservice.sdk.auth.utils.redis.RedisUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashSet;
import java.util.Set;

public class UserAppService {
  private static final Logger log = LoggerFactory.getLogger(UserAppService.class);
  private static Set<String> keys = new HashSet<>();
  // 被服务app的服务域名 http://www.sense.com.cn

  /**
   * .
   */
  public UserAppService() {
    keys.add(AuthConstants.ACCESSKEY);
    keys.add(AuthConstants.NONCE);
    keys.add(AuthConstants.SIGN);
  }

  /**
   * @param url.
   * @return chk.
   */
  public ChkResult validateGet(String url) {
    log.debug("url:" + url);
    ChkResult result = new ChkResult();

    try {
      int ssaccesskeyIndex = url.indexOf(AuthConstants.ACCESSKEY);
      int ssnonceIndex = url.indexOf(AuthConstants.NONCE);
      int sssignIndex = url.indexOf(AuthConstants.SIGN);

      String ssaccesskey = url.substring(ssaccesskeyIndex 
          + AuthConstants.ACCESSKEY.length() + 1, ssnonceIndex - 1);

      String ssnonce = url.substring(ssnonceIndex 
           + AuthConstants.NONCE.length() + 1, sssignIndex - 1);

      // 防止重复提交同一数据
      String nonceKey = ssaccesskey + AuthConstants.NONCE;
      String nonce = RedisUtil.get(nonceKey);
      if (nonce != null && ssnonce.equals(nonce)) {
        result.setResult(false);
        result.setStatus(ErrorCode.ERROR_NONCE);
        return result;
      } else {
        // 签名验证
        String sssign = url.substring(sssignIndex + AuthConstants.SIGN.length() + 1, url.length());

        String secret = SdkPropUtil.getSecretFromMap(ssaccesskey);

        if (secret != null) {

          String action = StringUtils.getAction(url);

          int begin = url.indexOf(action);

          String signStr = url.substring(begin, sssignIndex) 
              + AuthConstants.SECRET + "=" + secret;

          String sign = MD5Utils.md5(signStr);

          if (sssign.equals(sign)) {
            RedisUtil.setex(nonceKey, ssnonce, 300);
            result.setResult(true);
            result.setStatus(ErrorCode.OK);
            return result;
          } else {
            result.setResult(false);
            result.setStatus(ErrorCode.ERROR_SIGN);
            return result;
          }
          //
        } else {
          result.setResult(false);
          result.setStatus(ErrorCode.ERROR_ACCESSKEY);
          return result;
        }
      }
    } catch ( Exception exec ) {
      result.setResult(false);
      result.setStatus(ErrorCode.ERROR_ACCESS);
    }
    return result;

  }

  /**
   * @param url.
   * @param b2.
   * @return chk .
   */
  public ChkResult validatePost(String url, byte[] b2) {
    log.debug("url:" + url);

    ChkResult result = new ChkResult();
    try {
      int ssaccesskeyIndex = url.indexOf(AuthConstants.ACCESSKEY);
      int ssnonceIndex = url.indexOf(AuthConstants.NONCE);
      int sssignIndex = url.indexOf(AuthConstants.SIGN);

      String ssaccesskey = url.substring(ssaccesskeyIndex 
          + AuthConstants.ACCESSKEY.length() + 1, ssnonceIndex - 1);

      String ssnonce = url.substring(ssnonceIndex + AuthConstants.NONCE.length() 
             + 1, sssignIndex - 1);

      // 防止重复提交同一数据
      String nonceKey = ssaccesskey + AuthConstants.NONCE;
      String nonce = RedisUtil.get(nonceKey);
      if (nonce != null && ssnonce.equals(nonce)) {
        result.setResult(false);
        result.setStatus(ErrorCode.ERROR_NONCE);
        return result;
      } else {
        // 签名验证
        String sssign = url.substring(sssignIndex + AuthConstants.SIGN.length() + 1, url.length());

        String secret = SdkPropUtil.getSecretFromMap(ssaccesskey);

        if (secret != null) {
          String action = StringUtils.getAction(url);

          int begin = url.indexOf(action);

          String signStr = url.substring(begin, sssignIndex) 
                  + AuthConstants.SECRET + "=" + secret;

          byte[] b1 = signStr.getBytes();

          byte[] data = new byte[b1.length + b2.length];

          System.arraycopy(b1, 0, data, 0, b1.length);

          System.arraycopy(b2, 0, data, b1.length, b2.length);

          String sign = MD5Utils.md5(data);

          if (sssign.equals(sign)) {
            RedisUtil.setex(nonceKey, ssnonce, 300);
            result.setResult(true);
            result.setStatus(ErrorCode.OK);
            return result;
          } else {
            result.setResult(false);
            result.setStatus(ErrorCode.ERROR_SIGN);
            return result;
          }
          //
        } else {
          result.setResult(false);
          result.setStatus(ErrorCode.ERROR_ACCESSKEY);
          return result;
        }
      }
    } catch (Exception exec) {
      result.setResult(false);
      result.setStatus(ErrorCode.ERROR_ACCESS);
    }
    return result;

  }

  //
}
